/*
 * pthreadHelper.h
 *
 *  Created on: Feb 5, 2010
 *      Author: Jamie LaPointe
 */

#ifndef PTHREADHELPER_H_
#define PTHREADHELPER_H_

#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>

#ifdef __cplusplus
extern "C"
{
#endif

//
// Create a new POSIX thread, checking for errors and reporting as appropriate.
//
inline void createPthread(pthread_t * const new_thread_ID,
      const pthread_attr_t * const attr, void * (* start_func)(
            void * ), void * const arg)
{
   if (pthread_create(new_thread_ID, attr, start_func, arg))
   {
      perror(NULL);
      abort();
   }
}

//
// Initialize a new POSIX thread attribute type properly checking for errors.
//
inline void initAttrPthread(pthread_attr_t * const a)
{
   if (pthread_attr_init(a))
   {
      perror(NULL);
      abort();
   }
}

//
// Initialize a new POSIX thread condition attribute, properly checking for errors.
//
inline void initPthreadCondAttr(pthread_condattr_t * const a)
{
   if (pthread_condattr_init(a))
   {
      perror(NULL);
      abort();
   }
}

//
// Initialize a new POSIX thread mutex attribute, properly checking for errors.
//
inline void initPthreadMutexAttr(pthread_mutexattr_t * const a)
{
   if (pthread_mutexattr_init(a))
   {
      perror(NULL);
      abort();
   }
}

//
// Initialize a new semaphore, properly checking for errors.
//
inline void initSem(sem_t * const sem, int pshared, unsigned int value)
{
   if (sem_init(sem, pshared, value))
   {
      perror(NULL);
      abort();
   }
}

//
// Properly wait for a semaphore
//
inline void waitSem(sem_t * const arg)
{
   while (sem_wait(arg) != 0)
   {
   }
}

//
// Block one thread, waiting for the other threads to signal the semaphore
// up to the count variable... This is useful for having the main thread block
// waiting for a number of worker threads to finish their job before continuing
// (usually to collect their shared data).
//
inline void threadSingleBarrier(sem_t * const barrier, int count)
{
   while (count > 0)
   {
      waitSem(barrier);
      count--;
   }
}

#ifdef __cplusplus
}
#endif

#endif /* PTHREADHELPER_H_ */
